#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   card_reissue_test.py
@Time    :   2025/04/17 13:31:28
@Author  :   YangLiang 
@Version :   1.0
@Contact :   yangl@genvict.com
@License :   (C)Copyright 2022-2025
@Desc    :   卡片二次发行流程测试
'''

from pytest_assume.plugin import assume
import pytest
import logging
import time
from commDriver.TS_CAN import *
import allure
import sys
sys.dont_write_bytecode = True

class Test_Card_Reissue:
    # APDU命令定义
    IntoPsam3F00 = "00A40000023F00"
    IntoPsamDF01 = "00A4000002DF01"
    IntoOBU3F00 = "00A40000023F00"
    
    @allure.severity('critical')
    @allure.title('卡片二次发行流程测试')
    @allure.description('验证完整的卡片二次发行流程')
    def test_card_reissue_process(self, action, Driver):
        iStep = 1
        
        # 1. 获取OBU系统信息
        with allure.step(f'第{iStep}步: 获取OBU系统信息'):
            iStep, obu_system_info = Driver['CAN'].getOBUSystemInfo(iStep)
            with assume: assert len(obu_system_info) >= 18, logging.error("OBU系统信息长度不足18字节")
            iStep += 1

        # 2. 提取关键信息
        with allure.step(f'第{iStep}步: 提取地区代码和OBU序列号'):
            # 地区代码 D_SN = 前4字节 + 前4字节
            d_sn = obu_system_info[:4] + obu_system_info[:4]
            # OBU序列号 O_SN = 第10-17字节(从0开始)
            o_sn = obu_system_info[10:18]
            
            with assume: assert len(d_sn) == 8, logging.error("地区代码长度应为8字节")
            with assume: assert len(o_sn) == 8, logging.error("OBU序列号长度应为8字节")
            iStep += 1

        # 3. 进入PSAM目录
        with allure.step(f'第{iStep}步: 进入PSAM目录'):
            iStep, response = Driver['CAN'].sendAPDU(iStep, self.IntoPsam3F00)
            with assume: assert response == "9000", logging.error("进入PSAM 3F00目录失败")
            iStep += 1

        # 4. 进入OBU目录
        with allure.step(f'第{iStep}步: 进入OBU目录'):
            iStep, response = Driver['CAN'].sendAPDU(iStep, self.IntoOBU3F00)
            with assume: assert response == "9000", logging.error("进入OBU 3F00目录失败")
            iStep += 1

        # 5. 写入地区代码
        with allure.step(f'第{iStep}步: 写入地区代码'):
            write_cmd = f"80D40000{len(d_sn):02X}{d_sn.hex()}"
            iStep, response = Driver['CAN'].sendAPDU(iStep, write_cmd)
            with assume: assert response == "9000", logging.error("写入地区代码失败")
            iStep += 1

        # 6. 写入OBU序列号
        with allure.step(f'第{iStep}步: 写入OBU序列号'):
            write_cmd = f"80D40001{len(o_sn):02X}{o_sn.hex()}"
            iStep, response = Driver['CAN'].sendAPDU(iStep, write_cmd)
            with assume: assert response == "9000", logging.error("写入OBU序列号失败")
            iStep += 1

        # 7. 验证写入结果
        with allure.step(f'第{iStep}步: 验证写入结果'):
            # 读取地区代码
            read_cmd = "80B0000008"
            iStep, response = Driver['CAN'].sendAPDU(iStep, read_cmd)
            with assume: assert response[:-2] == d_sn.hex(), logging.error("地区代码验证失败")
            
            # 读取OBU序列号
            read_cmd = "80B0000108"
            iStep, response = Driver['CAN'].sendAPDU(iStep, read_cmd)
            with assume: assert response[:-2] == o_sn.hex(), logging.error("OBU序列号验证失败")
            iStep += 1

        # 8. 激活OBU
        with allure.step(f'第{iStep}步: 激活OBU'):
            iStep, OBUSwitchSt = Driver['CAN'].setOBUSwitchSt(iStep, Enable=True)
            with assume: assert OBUSwitchSt == 0x02, logging.error("OBU激活失败")
            iStep += 1

    @allure.severity('normal')
    @allure.title('卡片二次发行异常流程测试')
    @allure.description('验证卡片二次发行的异常处理流程')
    def test_card_reissue_error_handling(self, action, Driver):
        iStep = 1
        
        # 1. 测试错误的PSAM目录进入
        with allure.step(f'第{iStep}步: 测试错误的PSAM目录进入'):
            wrong_cmd = "00A40000023F01"  # 错误的目录
            iStep, response = Driver['CAN'].sendAPDU(iStep, wrong_cmd)
            with assume: assert response != "9000", logging.error("错误目录进入不应成功")
            iStep += 1

        # 2. 测试错误的数据写入
        with allure.step(f'第{iStep}步: 测试错误的数据写入'):
            # 先进入正确的目录
            iStep, response = Driver['CAN'].sendAPDU(iStep, self.IntoPsam3F00)
            iStep, response = Driver['CAN'].sendAPDU(iStep, self.IntoOBU3F00)
            
            # 写入错误长度的数据
            wrong_data = "112233445566778899"  # 过长数据
            write_cmd = f"80D40000{len(wrong_data)//2:02X}{wrong_data}"
            iStep, response = Driver['CAN'].sendAPDU(iStep, write_cmd)
            with assume: assert response != "9000", logging.error("错误数据写入不应成功")
            iStep += 1